package team3.tracking;

import team3.tracking.services.LocationUpdateAndQuery;
import team3.tracking.services.TrackingInterface;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class P4_ClientTrackingActivity extends Activity {
	
	public static String BROADCAST_ACTION = "team3.tracking.broadcast";
	public static final String PREFS_NAME = "ClientTrackingPrefs";
	public static String BROADCAST_TYPE = "type";
	public static int UPDATE_UI = 1;
	public static int UPDATE_REMOTE_VALUES = 2;
	
	private Button startServiceButton;
    private Button stopServiceButton;
    private Button remotePositionButton;
    private Button exitButton;
	private TextView latitude_text;
	private TextView longitude_text;
	private TextView distance_text;
	private TextView avg_speed_text;
	private TextView ratio_text;
	private TextView remote_latitude_text;
	private TextView remote_longitude_text; 
	
    private double latitude;
    private double longitude;
    private double distance;
    private double averageSpeed;
    private double ratio;
    
    private Intent myIntent;
    private TrackingInterface trackingInterface;

    private boolean isBound = false;    //Will be used for checking the status of the Service
    
    private MyBroadcastReceiver mBroadcastReceiver;    
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
                
        setUpGUI();
        
        myIntent = new Intent(this, LocationUpdateAndQuery.class);
        mBroadcastReceiver = new MyBroadcastReceiver();
        System.out.println("on create activity");
    }    
    
    public class MyBroadcastReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context arg0, Intent intent) {
			int type = intent.getIntExtra(BROADCAST_TYPE, 0);
			if(type == UPDATE_UI)
				getValuesFromSensor();
			else if(type == UPDATE_REMOTE_VALUES && trackingInterface!=null){
				try {
					remote_latitude_text.setText(Double.toString(trackingInterface.getRemoteLatitude()));
					remote_longitude_text.setText(Double.toString(trackingInterface.getRemoteLongitude()));
				} catch (RemoteException e) {
					e.printStackTrace();
				}
            	
			}
				
		}
    	
    }
    
    private void setUpGUI(){    	
    	//User interface 
    	setContentView(R.layout.main);
        startServiceButton = (Button) findViewById(R.id.start_service_button);
        startServiceButton.setOnClickListener(startServiceButtonListener);
        stopServiceButton = (Button) findViewById(R.id.stop_service_button);
        stopServiceButton.setOnClickListener(stopServiceButtonListener);
        remotePositionButton = (Button) findViewById(R.id.get_remote_position_button);
        remotePositionButton.setOnClickListener(remotePositionButtonListener);       
        exitButton = (Button) findViewById(R.id.exit_button);
        exitButton.setOnClickListener(exitButtonListener);
        latitude_text = (TextView) findViewById(R.id.latitude_text);
        longitude_text = (TextView) findViewById(R.id.longitude_text);
        distance_text = (TextView) findViewById(R.id.distance_text);
        avg_speed_text = (TextView) findViewById(R.id.avg_speed_text);
        ratio_text = (TextView) findViewById(R.id.ratio_text);
        remote_latitude_text = (TextView) findViewById(R.id.remote_latitude_text);
        remote_longitude_text = (TextView) findViewById(R.id.remote_longitude_text);
    }
    
   
    public void onResume(){
    	super.onResume(); 
    	SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, 0);
        isBound = sharedPreferences.getBoolean("serviceConnected", false); //checks if service is running        														  
        														  //"false" is the default return value        						
    	if(isBound)
        	doBindService();
    	
    	IntentFilter filter = new IntentFilter(BROADCAST_ACTION);
    	this.registerReceiver(mBroadcastReceiver, filter);

    }
        
    public void onPause(){
    	super.onPause();  
    	SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, 0); //We have to save the variable isBound for avoid 
        SharedPreferences.Editor editor = sharedPreferences.edit(); //being deleted by the garbage collector
        editor.putBoolean("serviceConnected", isBound);
        // Commit the edits!
        editor.commit();
    	if(isBound)
        	doUnbindService();
    	this.unregisterReceiver(mBroadcastReceiver);
    }    

    public void onDestroy(){
    	super.onDestroy();
    }   
    
    void doBindService() {    	
		bindService(myIntent, myConnection, Context.BIND_AUTO_CREATE);
		isBound = true;
	}

    void doUnbindService() {
    	unbindService(myConnection);
    	isBound = false;
	}
    
    private ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the service object we can use to
            // interact with the service.  Because we have bound to a explicit
            // service that we know is running in our own process, we can
            // cast its IBinder to a concrete class and directly access it.        	
        	//trackServsInterface = TrackServsInterface.Stub.asInterface(service);
        	//positionInterface = PositionInterface.Stub.asInterface(service);
        	trackingInterface = TrackingInterface.Stub.asInterface(service);
        	getValuesFromSensor();

        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            // Because it is running in our same process, we should never
            // see this happen.        	
        	//trackServsInterface = null;
        	//positionInterface = null;
        	trackingInterface = null;
        }
    };    
  	
  	private OnClickListener startServiceButtonListener = new OnClickListener() {
        public void onClick(View v) {     
        	//Check the status of the service
        	if(isBound){
        		Toast toast = Toast.makeText(getApplicationContext(), 
    					"Service already running.", Toast.LENGTH_SHORT);        		
    			toast.show(); 
    			//System.out.println("already bound");
        	}
        	else{    
        		//System.out.println("start service now");
        		startService(myIntent);
        		doBindService();
        		
        	}
        }
  	};
  	
  	private OnClickListener stopServiceButtonListener = new OnClickListener() {
        public void onClick(View v) {

        	if(isBound){
        		doUnbindService();
        		stopService(myIntent);
        		
        	} else {
        		Toast toast = Toast.makeText(getApplicationContext(), 
    					"Service already stopped.", Toast.LENGTH_SHORT);
    			toast.show();
        	}
        }
    };
    
    private OnClickListener exitButtonListener = new OnClickListener() {
        public void onClick(View v) {
        	finish();
        }
    };    
     
    
    private void getValuesFromSensor(){

        if(trackingInterface != null){
        	System.out.println("tracking interface not null");
      		try {
      			//Assign values from trackingInterface service
      			latitude = trackingInterface.getLatitude();
      			longitude = trackingInterface.getLongitude();
      			distance = trackingInterface.getDistance();
      			averageSpeed = trackingInterface.getAverageSpeed();
      			ratio = trackingInterface.getRatio();
      		} catch (RemoteException e) {
      			e.printStackTrace();
      		}
      	} else {
      		System.out.println("tracking interface null");
      	}
        writeValuesOnGUI();
    }
    
    public void writeValuesOnGUI(){
    	//Write values to GUI
    	longitude_text.setText(Double.toString(longitude));    	
    	latitude_text.setText(Double.toString(latitude));    	
    	distance_text.setText(Double.toString(distance));    	
    	avg_speed_text.setText(Double.toString(averageSpeed)); 
    	ratio_text.setText(Double.toString(ratio));
    	
    }
    
    
    private OnClickListener remotePositionButtonListener = new OnClickListener() {
        public void onClick(View v) {
        	
        	//     trigger a TCP query to server
        	
            if(trackingInterface != null){
	
	        	try{	
	        		//Call service to Query server about the position
	        		trackingInterface.queryServer();  
	        		}	        		
	        		catch(NullPointerException error){
	        		System.out.println("NULL POINTER EXCEPTION");
	        		} catch (RemoteException e) {
						e.printStackTrace();
					}
        	
            }
            
        }
            
    };
       
}